import BaseVue from '@/lib/base/BaseVue';
import { VueReactiveListener } from '@/lib/directives/ImageLazyload';
import Component from 'vue-class-component';
import { Prop, Watch } from 'vue-property-decorator';
import lazyConfig from '@/config/lazyload';

@Component
export default class LazyImage extends BaseVue {
    @Prop()
    private src!: string;
    @Prop()
    private loop!: boolean;
    private state = 'loading';
    private isErr = false;
    private url = '';
    private classSelector = Date.now() + '_' + Math.floor(Math.random() * 100000);

    private get showUrl() {
        if (this.isErr) {
            return lazyConfig.error as string;
        } else if (!this.url) {
            return lazyConfig.loading as string;
        } else {
            return this.url;
        }
    }

    public render() {
        return (
            <div key={this.src}
                class={this.classSelector}
                lazy={this.state}
                style={{ backgroundImage: `url(${this.showUrl})` }}></div>
        );
    }

    public created() {
        this.$nextTick(() => {
            this.loadImage();
        });
    }

    private setLoop(src: string, state: string) {
        this.state = state;
        if (!this.loop) {
            return;
        }
        this.$nextTick(() => {
            const doms = document.getElementsByClassName(this.classSelector);
            for (let i = 0, len = doms.length; i < len; i++) {
                const dom = doms[i] as HTMLElement;
                if (dom != this.$el) {
                    dom.style.backgroundImage = `url(${src})`;
                    if (dom.getAttribute('lazy') !== state) {
                        dom.setAttribute('lazy', state);
                    }

                }
            }
        });

    }

    @Watch('src')
    private async loadImage() {
        if (!this.src) {
            this.isErr = true;
            this.setLoop(this.showUrl, 'error');
            return;
        }


        this.setLoop(this.showUrl, 'loading');
        const url = await this.getImageFileCache();
        let image = new Image();

        image.onload = () => {
            this.url = url;
            this.setLoop(this.showUrl, 'loaded');
        }

        image.onerror = (e) => {
            this.isErr = true;
            this.setLoop(this.showUrl, 'error');
        }

        image.src = url;
    }


    private getImageFileCache() {
        return new Promise<string>((res) => {
            const isAliCDN = /alicdn.com/;
            const isCache = /_\d+x\d+\.(jpg|png|gif|jpeg)/;
            const src = isAliCDN.test(this.src) && !isCache.test(this.src) ? this.src + '_400x400Q50s50.jpg' : this.src;

            if (location.protocol === 'file:' && typeof api !== 'undefined') {
                window['api'].imageCache({
                    url: src,
                    policy: 'cache_only',
                    thumbnail: false
                }, function (ret) {
                    res(ret.url);
                });
            } else {
                res(src);
            }
        });
    }
}
